import os
import json
import requests
import tkinter as tk
from tkinter import filedialog, messagebox
from parse_docx import parse_docx

# 配置文件路径
CONFIG_PATH = 'config_help.json'

# 保存配置函数
def save_config(config):
    """保存配置到文件"""
    # 添加版本标识并清理旧配置
    config['config_version'] = '2.0'
    config.pop('format_md', None)
    config.pop('format_docx', None)
    with open(CONFIG_PATH, 'w', encoding='utf-8') as f:
        json.dump(config, f, ensure_ascii=False, indent=4)

# 加载配置函数
def load_config():
    """从配置文件加载配置"""
    if os.path.exists(CONFIG_PATH):
        try:
            with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
                config = json.load(f)
                # 处理旧版本配置迁移
                if 'format_md' in config:
                    config['format_type'] = 'md' if config.get('format_md') else 'docx'
                return config
        except:
            return {}
    return {}

def generate_homework(question):
    """调用DeepSeek API生成作业答案（JSON格式）"""
    # 从配置中获取API KEY
    api_key = config.get('api_key', '')
    if not api_key:
        messagebox.showerror("错误", "请先设置API KEY！")
        return None
    
    api_url = "https://api.deepseek.com/v1/chat/completions"
    
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    
    payload = {
        "model": "deepseek-coder",
        "messages": [
            {
                "role": "system",
                "content": "你是一个作业助手，需要根据题目要求生成完整的作业答案。"
                           "返回格式必须是JSON：{'markdown_content': '作业内容'}"
            },
            {
                "role": "user",
                "content": f"作业题目：\n{question}\n\n"
                           "请生成完整的作业答案（Markdown格式），"
                           "使用JSON格式返回，包含markdown_content字段。"
            }
        ],
        "temperature": 0.95,  # 增加随机性
        "max_tokens": 8000, 
        "response_format": {"type": "json_object"}
    }
    
    try:
        response = requests.post(api_url, headers=headers, json=payload, timeout=120)
        response.raise_for_status()
        print(f"API原始响应: {response.text}")
        response_data = response.json()
        print(f"解析后的响应数据: {json.dumps(response_data, ensure_ascii=False)}")
        return response_data['choices'][0]['message']['content']
    except Exception as e:
        messagebox.showerror("API请求失败", f"错误信息: {str(e)}")
        return None

def process_unsubmitted():
    """处理未提交的作业目录"""
    # 禁用处理按钮，防止重复点击
    process_btn.config(state=tk.DISABLED)
    # 更新状态栏
    status_bar.config(text="开始处理未提交作业...")
    root.update()  # 强制更新UI
    # 检查API KEY有效性
    api_key = config.get('api_key', '')
    if not api_key:
        messagebox.showerror("错误", "请先设置API KEY！")
        process_btn.config(state=tk.NORMAL)
        status_bar.config(text="就绪")
        return

    question_path = question_entry.get()
    directory_path = directory_entry.get()
    
    # 保存当前输入框内容
    config['question_path'] = question_path
    config['directory_path'] = directory_path
    save_config(config)
    
    if not os.path.exists(question_path) or not os.path.exists(directory_path):
        messagebox.showerror("错误", "路径不存在！")
        process_btn.config(state=tk.NORMAL)
        status_bar.config(text="就绪")
        return
    
    # 读取作业题目
    try:
        if question_path.lower().endswith('.docx'):
            question = parse_docx(question_path)
            if '解析失败' in question:
                raise Exception(question)
        else:
            with open(question_path, 'r', encoding='utf-8') as f:
                question = f.read()
    except Exception as e:
        messagebox.showerror("错误", f"读取题目失败: {e}")
        process_btn.config(state=tk.NORMAL)
        status_bar.config(text="就绪")
        return
    
    # 查找未提交目录
    unsubmitted_dirs = [d for d in os.listdir(directory_path) 
                       if "(未提交)" in d and os.path.isdir(os.path.join(directory_path, d))]
    
    if not unsubmitted_dirs:
        messagebox.showinfo("完成", "没有找到未提交的作业目录")
        process_btn.config(state=tk.NORMAL)
        status_bar.config(text="就绪")
        return
    
    total = len(unsubmitted_dirs)
    # 处理每个未提交目录
    success_count = 0
    for i, dir_name in enumerate(unsubmitted_dirs):
        # 更新状态栏显示当前处理进度
        status_bar.config(text=f"正在处理: {dir_name} ({i+1}/{total})")
        root.update()  # 强制更新UI
        
        try:
            # 调用API获取答案
            api_response = generate_homework(question)
            if not api_response:
                continue
                
            # 解析JSON获取Markdown内容
            response_data = json.loads(api_response)
            markdown_content = response_data.get('markdown_content', '')
            
            # 生成Markdown文件
            clean_name = dir_name.replace("-(未提交)", "").strip()
            output_base = os.path.join(directory_path, dir_name, clean_name)
            output_path = output_base + '.md'
            if markdown_content:
                output_base = os.path.splitext(output_path)[0]
                
                if format_var.get() == 'md':
                    with open(output_base + '.md', 'w', encoding='utf-8') as md_file:
                        md_file.write(markdown_content)
                    success_count += 1  # 新增计数
                else:
                    try:
                        from convert_md_to_docx import md_to_docx
                        md_to_docx(markdown_content, output_base + '.docx')
                        success_count += 1
                    except Exception as e:
                        messagebox.showerror("转换错误", f"Word文档生成失败: {str(e)}")
                        # 转换失败时使用默认文件名
                        fallback_path = os.path.join(directory_path, dir_name, "作业.docx")
                        md_to_docx(markdown_content, fallback_path)
                        success_count += 1
                
        except Exception as e:
            print(f"处理目录 {dir_name} 失败: {e}")
    
    # 更新状态栏显示最终结果
    status_bar.config(text=f"完成! 成功处理 {success_count}/{total} 个学生的作业")
    messagebox.showinfo("完成", f"成功处理 {success_count}/{len(unsubmitted_dirs)} 个作业")
    process_btn.config(state=tk.NORMAL)

def open_settings():
    """打开设置窗口"""
    settings_window = tk.Toplevel(root)
    settings_window.title("API 设置")
    settings_window.geometry("500x200")
    settings_window.resizable(False, False)
    
    # 设置窗口图标
    try:
        settings_window.iconbitmap("settings_icon.ico")
    except:
        pass
    
    # API KEY标签和输入框
    tk.Label(settings_window, text="DeepSeek API KEY:", font=("Arial", 11)).pack(pady=(20, 5))
    api_entry = tk.Entry(settings_window, width=50, show="*")
    api_entry.pack()
    api_entry.insert(0, config.get('api_key', ''))
    
    # 保存按钮
    def save_settings():
        config['api_key'] = api_entry.get()
        save_config(config)
        messagebox.showinfo("保存成功", "API KEY已保存！")
        settings_window.destroy()
    
    save_btn = tk.Button(settings_window, text="保存设置", command=save_settings, 
                         bg="#4CAF50", fg="white", height=1, width=15, font=("Arial", 10))
    save_btn.pack(pady=20)
    
    # 帮助文本
    help_text = tk.Label(settings_window, 
                         text="提示：您可以在DeepSeek官网获取API KEY",
                         fg="gray", font=("Arial", 9))
    help_text.pack(side=tk.BOTTOM, pady=5)

# 创建GUI界面
root = tk.Tk()
root.title("AI作业助手")
root.geometry("600x350")
try:
    root.iconbitmap("app_icon.ico")
except:
    pass

# 加载配置
config = load_config()

# 创建菜单栏
menu_bar = tk.Menu(root)
root.config(menu=menu_bar)

# 添加"设置"菜单
settings_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="设置", menu=settings_menu)
settings_menu.add_command(label="API设置", command=open_settings)
settings_menu.add_separator()
settings_menu.add_command(label="退出", command=root.quit)

# 主界面框架
main_frame = tk.Frame(root, padx=20, pady=20)
main_frame.pack(fill=tk.BOTH, expand=True)

# 作业题目输入框
tk.Label(main_frame, text="作业题目文件路径:", font=("Arial", 10)).pack(anchor=tk.W, pady=(5, 0))
question_frame = tk.Frame(main_frame)
question_frame.pack(fill=tk.X, pady=5)
question_entry = tk.Entry(question_frame, width=50, font=("Arial", 10))
question_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
question_entry.insert(0, config.get('question_path', ''))
# 添加浏览按钮
def browse_question_file():
    file_path = filedialog.askopenfilename(title="选择作业题目文件")
    if file_path:
        question_entry.delete(0, tk.END)
        question_entry.insert(0, file_path)
tk.Button(question_frame, text="浏览...", command=browse_question_file, width=8).pack(side=tk.RIGHT, padx=(5, 0))

# 目录路径输入框
tk.Label(main_frame, text="作业目录路径:", font=("Arial", 10)).pack(anchor=tk.W, pady=(10, 0))
directory_frame = tk.Frame(main_frame)
directory_frame.pack(fill=tk.X, pady=5)
directory_entry = tk.Entry(directory_frame, width=50, font=("Arial", 10))
directory_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
directory_entry.insert(0, config.get('directory_path', ''))
# 添加浏览按钮
def browse_directory():
    dir_path = filedialog.askdirectory(title="选择作业目录")
    if dir_path:
        directory_entry.delete(0, tk.END)
        directory_entry.insert(0, dir_path)
tk.Button(directory_frame, text="浏览...", command=browse_directory, width=8).pack(side=tk.RIGHT, padx=(5, 0))

# 处理按钮
btn_frame = tk.Frame(main_frame)
btn_frame.pack(fill=tk.X, pady=20)
process_btn = tk.Button(btn_frame, text="处理未提交作业", command=process_unsubmitted, 
                        height=2, width=20, bg="#2196F3", fg="white", font=("Arial", 10, "bold"))
process_btn.pack()

# 状态栏 - 显示处理进度
status_bar = tk.Label(root, text="就绪", bd=1, relief=tk.SUNKEN, anchor=tk.W, padx=10, 
                     font=("Arial", 9), fg="#333333")
status_bar.pack(side=tk.BOTTOM, fill=tk.X)

# 添加格式选择框
format_frame = tk.Frame(main_frame)
format_frame.pack(fill=tk.X, pady=10)

# 将复选框改为单选按钮组
format_var = tk.StringVar(value='md')
tk.Radiobutton(format_frame, text="生成md文件", variable=format_var, value='md', font=('Arial', 10)).pack(side=tk.LEFT, padx=5)
tk.Radiobutton(format_frame, text="word文档功能开发中", variable=format_var, value='docx', font=('Arial', 10)).pack(side=tk.LEFT, padx=5)

# 为输入框添加自动保存功能
def save_inputs(_event=None):
    config['question_path'] = question_entry.get()
    config['directory_path'] = directory_entry.get()
    config['format_type'] = format_var.get()
    save_config(config)

question_entry.bind('<KeyRelease>', save_inputs)
directory_entry.bind('<KeyRelease>', save_inputs)
format_var.trace('w', lambda *args: save_inputs())

# 加载配置处更新
format_var.set(config.get('format_type', 'md'))

root.mainloop()